<!DOCTYPE HTML>
<!--
	Dimension by HTML5 UP
	html5up.net | @ajlkn
	Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html>
 <head>
  <title>
   Dimension by HTML5 UP
  </title>
  <!-- <meta charset="utf-8" /> -->
  <!-- <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> -->
  <meta charset="utf-8"/>
  <meta content="width=device-width,initial-scale=1.0" name="viewport"/>
  <link href="../../assets/css/article.css" rel="stylesheet"/>
  <link href="https://cdn.bootcss.com/highlight.js/9.15.8/styles/github.min.css" rel="stylesheet"/>
  <noscript>
   <link href="../../assets/css/noscript.css" rel="stylesheet"/>
  </noscript>
 </head>
 <body>
  <div id="app">
  </div>
  <!-- built files will be auto injected -->
 </body>
 <body class="is-preload">
  <!-- Wrapper -->
  <div id="wrapper">
   <!-- Main -->
   <div id="main">
    <article id="article">
     <h1 id="gson-intdouble">
      Gson 序列化与反序列化时 将Int类型转换成Double类型 修改
     </h1>
     <hr/>
     <h2 id="_1">
      简介
     </h2>
     <p>
      在使用Gson进行数据的序列化和反序列化时，会出现将Int类型转为Double类型的现象，但我们需要区分Int和double，本文将介绍如何修改
     </p>
     <h2 id="_2">
      序列化和反序列化修改
     </h2>
     <p>
      我们可以通过定时序列化和反序列化的相关实现类，重新编写类型
     </p>
     <p>
      下面两个是针对Object和Map的，代码如下：
     </p>
     <div class="codehilite">
      <pre><span></span><code>    <span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">DataTypeAdapter</span> <span class="kd">extends</span> <span class="n">TypeAdapter</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="kd">private</span> <span class="kd">final</span> <span class="n">TypeAdapter</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">delegate</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Gson</span><span class="p">().</span><span class="na">getAdapter</span><span class="p">(</span><span class="n">Object</span><span class="p">.</span><span class="na">class</span><span class="p">);</span>

        <span class="nd">@Override</span>
        <span class="kd">public</span> <span class="n">Object</span> <span class="nf">read</span><span class="p">(</span><span class="n">JsonReader</span> <span class="n">in</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">IOException</span> <span class="p">{</span>
            <span class="n">JsonToken</span> <span class="n">token</span> <span class="o">=</span> <span class="n">in</span><span class="p">.</span><span class="na">peek</span><span class="p">();</span>
            <span class="k">switch</span> <span class="p">(</span><span class="n">token</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">case</span> <span class="n">BEGIN_ARRAY</span><span class="p">:</span>
                    <span class="n">List</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;&gt;</span><span class="p">();</span>
                    <span class="n">in</span><span class="p">.</span><span class="na">beginArray</span><span class="p">();</span>
                    <span class="k">while</span> <span class="p">(</span><span class="n">in</span><span class="p">.</span><span class="na">hasNext</span><span class="p">())</span> <span class="p">{</span>
                        <span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">read</span><span class="p">(</span><span class="n">in</span><span class="p">));</span>
                    <span class="p">}</span>
                    <span class="n">in</span><span class="p">.</span><span class="na">endArray</span><span class="p">();</span>
                    <span class="k">return</span> <span class="n">list</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">BEGIN_OBJECT</span><span class="p">:</span>
                    <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">map</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LinkedTreeMap</span><span class="o">&lt;&gt;</span><span class="p">();</span>
                    <span class="n">in</span><span class="p">.</span><span class="na">beginObject</span><span class="p">();</span>
                    <span class="k">while</span> <span class="p">(</span><span class="n">in</span><span class="p">.</span><span class="na">hasNext</span><span class="p">())</span> <span class="p">{</span>
                        <span class="n">map</span><span class="p">.</span><span class="na">put</span><span class="p">(</span><span class="n">in</span><span class="p">.</span><span class="na">nextName</span><span class="p">(),</span> <span class="n">read</span><span class="p">(</span><span class="n">in</span><span class="p">));</span>
                    <span class="p">}</span>
                    <span class="n">in</span><span class="p">.</span><span class="na">endObject</span><span class="p">();</span>
                    <span class="k">return</span> <span class="n">map</span><span class="p">;</span>

                <span class="k">case</span> <span class="n">STRING</span><span class="p">:</span>
                    <span class="k">return</span> <span class="n">in</span><span class="p">.</span><span class="na">nextString</span><span class="p">();</span>

                <span class="k">case</span> <span class="n">NUMBER</span><span class="p">:</span>
                    <span class="cm">/**</span>
<span class="cm">                     * 改写数字的处理逻辑，将数字值分为整型与浮点型。</span>
<span class="cm">                     */</span>
                    <span class="kt">double</span> <span class="n">dbNum</span> <span class="o">=</span> <span class="n">in</span><span class="p">.</span><span class="na">nextDouble</span><span class="p">();</span>

                    <span class="c1">// 数字超过long的最大值，返回浮点类型</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">dbNum</span> <span class="o">&gt;</span> <span class="n">Long</span><span class="p">.</span><span class="na">MAX_VALUE</span><span class="p">)</span> <span class="p">{</span>
                        <span class="k">return</span> <span class="n">dbNum</span><span class="p">;</span>
                    <span class="p">}</span>
                    <span class="c1">// 判断数字是否为整数值</span>
                    <span class="kt">long</span> <span class="n">lngNum</span> <span class="o">=</span> <span class="p">(</span><span class="kt">long</span><span class="p">)</span> <span class="n">dbNum</span><span class="p">;</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">dbNum</span> <span class="o">==</span> <span class="n">lngNum</span><span class="p">)</span> <span class="p">{</span>
                        <span class="k">try</span> <span class="p">{</span>
                            <span class="k">return</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">lngNum</span><span class="p">;</span>
                        <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
                            <span class="k">return</span> <span class="n">lngNum</span><span class="p">;</span>
                        <span class="p">}</span>
                    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                        <span class="k">return</span> <span class="n">dbNum</span><span class="p">;</span>
                    <span class="p">}</span>

                <span class="k">case</span> <span class="n">BOOLEAN</span><span class="p">:</span>
                    <span class="k">return</span> <span class="n">in</span><span class="p">.</span><span class="na">nextBoolean</span><span class="p">();</span>

                <span class="k">case</span> <span class="n">NULL</span><span class="p">:</span>
                    <span class="n">in</span><span class="p">.</span><span class="na">nextNull</span><span class="p">();</span>
                    <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>

<span class="nl">                default:</span>
                    <span class="k">throw</span> <span class="k">new</span> <span class="n">IllegalStateException</span><span class="p">();</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="nd">@Override</span>
        <span class="kd">public</span> <span class="kt">void</span> <span class="nf">write</span><span class="p">(</span><span class="n">JsonWriter</span> <span class="n">out</span><span class="p">,</span> <span class="n">Object</span> <span class="n">value</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">IOException</span> <span class="p">{</span>
            <span class="n">delegate</span><span class="p">.</span><span class="na">write</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">value</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">MapDeserializerDoubleAsIntFix</span> <span class="kd">implements</span> <span class="n">JsonDeserializer</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;&gt;</span><span class="p">{</span>

        <span class="nd">@Override</span>  <span class="nd">@SuppressWarnings</span><span class="p">(</span><span class="s">"unchecked"</span><span class="p">)</span>
        <span class="kd">public</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="nf">deserialize</span><span class="p">(</span><span class="n">JsonElement</span> <span class="n">json</span><span class="p">,</span> <span class="n">Type</span> <span class="n">typeOfT</span><span class="p">,</span> <span class="n">JsonDeserializationContext</span> <span class="n">context</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">JsonParseException</span> <span class="p">{</span>
            <span class="k">return</span> <span class="p">(</span><span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;</span><span class="p">)</span> <span class="n">read</span><span class="p">(</span><span class="n">json</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="kd">public</span> <span class="n">Object</span> <span class="nf">read</span><span class="p">(</span><span class="n">JsonElement</span> <span class="n">in</span><span class="p">)</span> <span class="p">{</span>

            <span class="k">if</span><span class="p">(</span><span class="n">in</span><span class="p">.</span><span class="na">isJsonArray</span><span class="p">()){</span>
                <span class="n">List</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;&gt;</span><span class="p">();</span>
                <span class="n">JsonArray</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">in</span><span class="p">.</span><span class="na">getAsJsonArray</span><span class="p">();</span>
                <span class="k">for</span> <span class="p">(</span><span class="n">JsonElement</span> <span class="n">anArr</span> <span class="p">:</span> <span class="n">arr</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">read</span><span class="p">(</span><span class="n">anArr</span><span class="p">));</span>
                <span class="p">}</span>
                <span class="k">return</span> <span class="n">list</span><span class="p">;</span>
            <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">in</span><span class="p">.</span><span class="na">isJsonObject</span><span class="p">()){</span>
                <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">map</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LinkedTreeMap</span><span class="o">&lt;&gt;</span><span class="p">();</span>
                <span class="n">JsonObject</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">in</span><span class="p">.</span><span class="na">getAsJsonObject</span><span class="p">();</span>
                <span class="n">Set</span><span class="o">&lt;</span><span class="n">Map</span><span class="p">.</span><span class="na">Entry</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">JsonElement</span><span class="o">&gt;&gt;</span> <span class="n">entitySet</span> <span class="o">=</span> <span class="n">obj</span><span class="p">.</span><span class="na">entrySet</span><span class="p">();</span>
                <span class="k">for</span><span class="p">(</span><span class="n">Map</span><span class="p">.</span><span class="na">Entry</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">JsonElement</span><span class="o">&gt;</span> <span class="n">entry</span><span class="p">:</span> <span class="n">entitySet</span><span class="p">){</span>
                    <span class="n">map</span><span class="p">.</span><span class="na">put</span><span class="p">(</span><span class="n">entry</span><span class="p">.</span><span class="na">getKey</span><span class="p">(),</span> <span class="n">read</span><span class="p">(</span><span class="n">entry</span><span class="p">.</span><span class="na">getValue</span><span class="p">()));</span>
                <span class="p">}</span>
                <span class="k">return</span> <span class="n">map</span><span class="p">;</span>
            <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="n">in</span><span class="p">.</span><span class="na">isJsonPrimitive</span><span class="p">()){</span>
                <span class="n">JsonPrimitive</span> <span class="n">prim</span> <span class="o">=</span> <span class="n">in</span><span class="p">.</span><span class="na">getAsJsonPrimitive</span><span class="p">();</span>
                <span class="k">if</span><span class="p">(</span><span class="n">prim</span><span class="p">.</span><span class="na">isBoolean</span><span class="p">()){</span>
                    <span class="k">return</span> <span class="n">prim</span><span class="p">.</span><span class="na">getAsBoolean</span><span class="p">();</span>
                <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">prim</span><span class="p">.</span><span class="na">isString</span><span class="p">()){</span>
                    <span class="k">return</span> <span class="n">prim</span><span class="p">.</span><span class="na">getAsString</span><span class="p">();</span>
                <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">prim</span><span class="p">.</span><span class="na">isNumber</span><span class="p">()){</span>

                    <span class="n">Number</span> <span class="n">num</span> <span class="o">=</span> <span class="n">prim</span><span class="p">.</span><span class="na">getAsNumber</span><span class="p">();</span>
                    <span class="c1">// here you can handle double int/long values</span>
                    <span class="c1">// and return any type you want</span>
                    <span class="c1">// this solution will transform 3.0 float to long values</span>
                    <span class="k">if</span><span class="p">(</span><span class="n">Math</span><span class="p">.</span><span class="na">ceil</span><span class="p">(</span><span class="n">num</span><span class="p">.</span><span class="na">doubleValue</span><span class="p">())</span>  <span class="o">==</span> <span class="n">num</span><span class="p">.</span><span class="na">longValue</span><span class="p">())</span>
                        <span class="k">return</span> <span class="n">num</span><span class="p">.</span><span class="na">longValue</span><span class="p">();</span>
                    <span class="k">else</span><span class="p">{</span>
                        <span class="k">return</span> <span class="n">num</span><span class="p">.</span><span class="na">doubleValue</span><span class="p">();</span>
                    <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span>
            <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre>
     </div>
     <p>
      然后在Gson初始化进行设置即可：
     </p>
     <div class="codehilite">
      <pre><span></span><code><span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Gson</span> <span class="n">GSON</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GsonBuilder</span><span class="p">()</span>
            <span class="p">.</span><span class="na">registerTypeAdapter</span><span class="p">(</span><span class="n">String</span><span class="p">.</span><span class="na">class</span><span class="p">,</span> <span class="k">new</span> <span class="n">StringTypeAdapter</span><span class="p">())</span>
            <span class="p">.</span><span class="na">registerTypeHierarchyAdapter</span><span class="p">(</span><span class="n">Pair</span><span class="p">.</span><span class="na">class</span><span class="p">,</span> <span class="k">new</span> <span class="n">PairTypeAdapter</span><span class="p">())</span>
            <span class="p">.</span><span class="na">registerTypeAdapter</span><span class="p">(</span><span class="k">new</span> <span class="n">TypeToken</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">Object</span><span class="o">&gt;&gt;</span><span class="p">()</span> <span class="p">{}.</span><span class="na">getType</span><span class="p">(),</span> <span class="k">new</span> <span class="n">DataTypeAdapter</span><span class="p">())</span>
            <span class="p">.</span><span class="na">registerTypeAdapter</span><span class="p">(</span><span class="n">Map</span><span class="p">.</span><span class="na">class</span><span class="p">,</span>  <span class="k">new</span> <span class="n">MapDeserializerDoubleAsIntFix</span><span class="p">())</span>
            <span class="p">.</span><span class="na">create</span><span class="p">();</span>
</code></pre>
     </div>
     <h2 id="_3">
      总结
     </h2>
     <p>
      上面是对 TypeToken
      <map\<string, object="">
       &gt;、Map的相关操作，如果还有其他情况，可以参考进行操作
      </map\<string,>
     </p>
    </article>
   </div>
   <!-- Footer -->
   <footer id="footer">
    <p class="copyright">
     © Untitled. Design:
     <a href="https://html5up.net">
      HTML5 UP
     </a>
     .
    </p>
   </footer>
  </div>
  <!-- BG -->
  <div id="bg">
  </div>
  <!-- Scripts -->
  <script src="../assets/js/jquery.min.js">
  </script>
  <script src="../assets/js/browser.min.js">
  </script>
  <script src="../assets/js/breakpoints.min.js">
  </script>
  <script src="../assets/js/util.js">
  </script>
  <script src="../assets/js/main.js">
  </script>
 </body>
</html>
